package cn.com.agree.bigdata.vmdatahandle.utils;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.Date;

import static org.quartz.JobBuilder.newJob;

/**
 * @description: Quartz manager
 * @author: LiYuan
 * @version: 1.0
 * @create: 2019-04-24
 **/
@Data
@Slf4j
public class QuartzManager {
    private static Scheduler sched;

    public QuartzManager() throws SchedulerException {
        init();
    }

    public void init() throws SchedulerException {
        SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
        sched = gSchedulerFactory.getScheduler();
    }

    /**
     * 添加job
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     * @param jobClass
     * @param time
     * @param scheduleJobName
     * @param scheduleJob
     */
    void addJob(String jobName,
                String jobGroupName,
                String triggerName,
                String triggerGroupName,
                Class<? extends Job> jobClass,
                String time, String scheduleJobName, Object scheduleJob) {

        log.info("add job:[jobName: {},jobGroupName:{},triggerName:{},triggerGroupName:{}]", jobName, jobGroupName, triggerName, triggerGroupName);

        try {
            JobDetail job = newJob(jobClass)
                    .withIdentity(jobName, jobGroupName)
                    .build();

            job.getJobDataMap().put(scheduleJobName, scheduleJob);

            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder
                    .newTrigger()
                    .withIdentity(triggerName, triggerGroupName)
                    .withSchedule(scheduleBuilder).build();
            Date ft = sched.scheduleJob(job, trigger);

            log.info("{} has been scheduled to run at:{} and repeat based on expression:{}", job.getKey(), ft, trigger.getCronExpression());

            // 启动
            if (!sched.isShutdown()) {
                log.info("-------Calling Starting Scheduler in addJob----------------");
                sched.start();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 删除job
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     */
    void removeJob(String jobName, String jobGroupName,
                   String triggerName, String triggerGroupName) {

        log.info("remove job:[jobName:{}, jobGroupName:{}, triggerName:{}, triggerGroupName:{}]", jobName, jobGroupName, triggerName, triggerGroupName);

        TriggerKey triggerKey = TriggerKey.triggerKey(
                triggerName, triggerGroupName);
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        try {
            sched.pauseTrigger(triggerKey);
            sched.unscheduleJob(triggerKey);
            sched.deleteJob(jobKey);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 显示启动定时调度器
     */
    void startJobs() {
        try {
            log.info("-------Calling Starting Scheduler explicitly----------------");
            sched.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

